package touchtrack.util;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;

/**
 * TrackPlayer
 * 
 * Plays MP3 files.
 * 
 * @author	MuMe09 team 6
 * 			http://mumetech.wordpress.com/
 */
public class TrackPlayer
{
	/**
	 * Plays an MP3 file.
	 * 
	 * @param 	String filename
	 */
	public static void play(String filename)
	{
		try 
		{
			File file = new File(filename);
			AudioInputStream in = AudioSystem.getAudioInputStream(file);
          	AudioFormat baseFormat = in.getFormat();
          	AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,  
            	baseFormat.getSampleRate(), 16, baseFormat.getChannels(),
            	baseFormat.getChannels() * 2,baseFormat.getSampleRate(), false);
          	AudioInputStream din = AudioSystem.getAudioInputStream(decodedFormat, in);
          	rawplay(decodedFormat, din);
          	in.close();
		}
		catch (Exception e)
		{
			// lol error
		}
    }

	/**
	 * @param 	AudioFormat
	 * @param 	AudioInputStream
	 * @throws 	IOException
	 * @throws 	LineUnavailableException
	 */
    private static void rawplay(AudioFormat targetFormat, AudioInputStream din) 
    	throws IOException, LineUnavailableException
    {
    	byte[] data = new byte[4096];
    	SourceDataLine line = getLine(targetFormat);
    	if (line != null)
    	{
    		// Start
    		line.start();
    		int nBytesRead = 0, nBytesWritten = 0;
    		while (nBytesRead != -1)
    		{
    			nBytesRead = din.read(data, 0, data.length);
    			if (nBytesRead != -1) 
    				nBytesWritten = line.write(data, 0, nBytesRead);
    		}
    		
    		// Stop
    		line.drain();
    		line.stop();
    		line.close();
    		din.close();
    	}
    }
    
    /**
     * @param 	AudioFormat
     * @return	SourceDataLine
     * @throws 	LineUnavailableException
     */
    private static SourceDataLine getLine(AudioFormat audioFormat) 
    	throws LineUnavailableException
    {
    	SourceDataLine res = null;
    	DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
    	res = (SourceDataLine) AudioSystem.getLine(info);
    	res.open(audioFormat);
    	return res;
    }
}